// Package config 实现了配置信息的管理
// 并根据配置文件完成相应的初始化配置。
package config

import (
	"log"
	"os"
	"path/filepath"
	"time"

	"github.com/spf13/viper"
)

type Config struct {
	App struct {
		Name string `mapstructure:"name"`
		Port string `mapstructure:"port"`
	} `mapstructure:"app"`
	Cors struct {
		Host         string        `mapstructure:"host"`
		Port         string        `mapstructure:"port"`
		MaxAge       time.Duration `mapstructure:"max_age"`
		AllowMethods []string      `mapstructure:"allow_methods"`
		AllowHeaders []string      `mapstructure:"allow_headers"`
	} `mapstructure:"cors"`
	JWT struct {
		Secret  string        `yaml:"secret"`
		Expires time.Duration `yaml:"expires"`
	}
	Database struct {
		Host         string `mapstructure:"host"`
		Port         string `mapstructure:"port"`
		User         string `mapstructure:"user"`
		Password     string `mapstructure:"password"`
		Name         string `mapstructure:"name"`
		MaxIdleConns int    `mapstructure:"max_idle_conns"`
		MaxOpenConns int    `mapstructure:"max_open_conns"`
	} `mapstructure:"database"`
}

var Instance *Config

func InitConfig() {
	// Loading config file
	cwd, _ := os.Getwd()
	viper.AddConfigPath(cwd)

	binPath, err := os.Executable()
	if err == nil {
		binDir := filepath.Dir(binPath)
		viper.AddConfigPath(binDir)
	}

	viper.SetConfigName("config")
	viper.SetConfigType("yaml")

	err = viper.ReadInConfig()
	if err != nil {
		log.Fatalf("Error reading config file: %v", err)
	}

	Instance = &Config{}

	err = viper.Unmarshal(Instance)
	if err != nil {
		log.Fatalf("Error decode config file into struct: %v", err)
	}

	initDB()
}
